package respacker

import (
	"crypto/md5"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strings"

	"gitee.com/StarCitizen_CN/stargox/pkg/fstools"
	"gitee.com/StarCitizen_CN/stargox/pkg/logger"
)

// dataMap[ralPath]fi
func Scan(dir string) (dataMap map[string]*L10nFileInfo, err error) {
	dataMap = make(map[string]*L10nFileInfo)

	pathList, err := fstools.ScanTree(dir)
	if err != nil {
		log.Fatalln(err)
		return
	}

	workCh := make(chan *L10nFileInfo, len(pathList))
	doScan := func(filePath string, wCh chan *L10nFileInfo) {

		data, err := os.ReadFile(filePath)
		if err != nil {
			log.Fatalln(err)
			return
		}

		md5hash := md5.New()
		md5hash.Write(data)
		md5hash.Sum(nil)
		md5 := fmt.Sprintf("%x", md5hash.Sum(nil))

		_, fileName := filepath.Split(filePath)
		fmt.Printf("%s %s\n", fileName, md5)

		relPath := strings.ReplaceAll(".\\"+filePath, dir+"\\", "")

		info := L10nFileInfo{
			RelPath: relPath,
			Name:    fileName,
			Data:    data,
			Md5:     md5,
		}

		wCh <- &info
	}

	for _, path := range pathList {
		go doScan(path, workCh)
	}

	for range pathList {
		newFi := <-workCh
		dataMap[newFi.RelPath] = newFi
	}

	return
}

func Write(releaseDir string, resMapArray []map[string]*L10nFileInfo) {

	for _, resMap := range resMapArray {

		doneCh := make(chan interface{}, len(resMap))
		uniqueCheckMap := make(map[string]*L10nFileInfo)
		for relPath, fi := range resMap {

			if uniqueFi := uniqueCheckMap[relPath]; uniqueFi != nil {
				logger.ShowGuiMsg("有问题了！", "别愣着赶紧联系船长驱虫")
				log.Fatalf("出现问题： %s", uniqueFi.RelPath)
			}

			go func(fi *L10nFileInfo, doneCh chan interface{}) {
				defer func() {
					doneCh <- nil
				}()
				writePath := filepath.Join(releaseDir, fi.RelPath)
				parent, _ := filepath.Split(writePath)

				_, err := os.Stat(parent)
				if os.IsNotExist(err) {
					err = nil
					os.MkdirAll(parent, os.ModeDir)
				}
				if err != nil {
					log.Fatalln(err)
				}

				err = os.WriteFile(writePath, fi.Data, 0644)
				if err != nil {
					err = fmt.Errorf("ops damn %w", err)
					log.Fatalln(err)
				}
			}(fi, doneCh)
		}

		for range resMap {
			<-doneCh
		}
	}

}
